package com.cheng.operation.impl;

import com.cheng.common.exception.CommonException;
import com.cheng.common.utils.DateUtil;
import com.cheng.common.utils.IdUtil;
import com.cheng.common.utils.StringUtil;
import com.cheng.data.entity.PermInfoEntity;
import com.cheng.data.entity.RoleInfoEntity;
import com.cheng.data.entity.RolePermEntity;
import com.cheng.data.entity.UserRoleEntity;
import com.cheng.data.vo.PermInfoVO;
import com.cheng.data.vo.ReqPageInfoVO;
import com.cheng.data.vo.RespPageInfoVO;
import com.cheng.data.vo.RoleInfoVO;
import com.cheng.operation.RoleInfoOperation;
import com.cheng.service.RoleInfoService;
import com.cheng.service.RolePermService;
import com.cheng.service.UserRoleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.management.relation.RoleInfo;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: ChengJW
 * @date: 2021/11/14 12:43
 * @version: 1.0
 * @description: 角色信息业务逻辑处理
 */
@Service
public class RoleInfoOperationImpl implements RoleInfoOperation {

    private final static Logger log = LoggerFactory.getLogger(RoleInfoOperationImpl.class);


    @Autowired
    private RoleInfoService roleInfoService;

    @Autowired
    private RolePermService rolePermService;

    @Autowired
    private UserRoleService userRoleService;

    /**
     * @author: ChengJW
     * @params: [pageInfoVO]
     * @return: com.cheng.data.vo.RespPageInfoVO
     * @date: 2021/11/15
     * @description: 查询角色列表信息，并分页按照layui统一格式返回
     */
    @Override
    public RespPageInfoVO queryRoleInfoList(ReqPageInfoVO pageInfoVO) throws CommonException {

        RoleInfoEntity entity = new RoleInfoEntity();
        //第一个查询参数为角色代码 roNm；第二个查询参数为角色中文描述 roDesc
        entity.setRoNm(String.valueOf(pageInfoVO.getQryReqFir()));
        entity.setRoDesc(String.valueOf(pageInfoVO.getQryReqSeco()));
        entity.setRoCode(pageInfoVO.getUserCode());
        PageInfo<RoleInfoEntity> pageInfo = PageHelper.startPage(pageInfoVO.getPageNum(),pageInfoVO.getPageSize()).doSelectPageInfo(() -> roleInfoService.queryRoleInfoList(entity));
        List<RoleInfoEntity> list = pageInfo.getList();
        RespPageInfoVO respPageInfoVO = new RespPageInfoVO();
        respPageInfoVO.setList(list);
        respPageInfoVO.setPageNum(pageInfo.getPageNum());
        respPageInfoVO.setPageSize(pageInfo.getPageSize());
        respPageInfoVO.setPageCount(pageInfo.getTotal());
        return respPageInfoVO;
    }

    /**
     * @author: ChengJW
     * @params: [roleInfoVO]
     * @return: void
     * @date: 2021/11/17
     * @description: 新增角色信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertRoleInfo(RoleInfoVO vo) throws CommonException {

        checkRoleInfo(vo);
        RoleInfoEntity entity = new RoleInfoEntity();
        BeanUtils.copyProperties(vo,entity);
        entity.setRoDelId("0");
        entity.setStDt(new Date());
        entity.setUtDt(new Date());
        roleInfoService.insertRoleInfo(entity);
        //插入 role_perm 表
        List<RolePermEntity> rolePermEntityList = new ArrayList<>();
        List<String> list = vo.getList();
        //去除重复数据
        list = list.stream().distinct().collect(Collectors.toList());
        for (int i = 0;i < list.size();i++){
            RolePermEntity rolePermEntity = new RolePermEntity();
            rolePermEntity.setRpId(IdUtil.getRPId(i));
            rolePermEntity.setRoId(vo.getRoId());
            rolePermEntity.setPrId(list.get(i));
            rolePermEntity.setStDt(new Date());
            rolePermEntity.setUtDt(new Date());
            rolePermEntityList.add(rolePermEntity);
        }
        rolePermService.insertBatchRolePerm(rolePermEntityList);
    }

    /**
    * @author: ChengJW
    * @params: []
    * @return: com.cheng.data.vo.RoleInfoVO
    * @date: 2021/11/17
    * @description: 根据角色 ID 查询角色信息
    */
    @Override
    public RoleInfoVO queryRoleInfoById(String roId) throws CommonException {

        RoleInfoVO roleInfoVO = new RoleInfoVO();
        RoleInfoEntity entity = roleInfoService.queryRoleInfoById(roId);
        BeanUtils.copyProperties(entity,roleInfoVO);
        return roleInfoVO;
    }

    /**
    * @author: ChengJW
    * @params: [roleInfoVO]
    * @return: void
    * @date: 2021/11/18
    * @description: 修改角色信息
    */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateRoleInfo(RoleInfoVO VO) throws CommonException {

        if (null == VO){
            log.error("角色信息为空，无法进行下一步操作");
            throw new CommonException("CJW202111010042","RoleInfoOperationImpl","updateRoleInfo");
        }
        //对角色ID，角色代码，角色名称，角色所属机关代码，角色菜单权限校验是否为空
        if (StringUtil.isNull(VO.getRoId()) || StringUtil.isNull(VO.getRoDesc()) || StringUtil.isNull(VO.getRoNm()) || StringUtil.isNull(VO.getRoCode()) || null == VO.getList() || VO.getList().size() == 0){
            log.error("角色信息填写不完全，无法进行下一步操作");
            throw new CommonException("CJW202111010045","RoleInfoOperationImpl","updateRoleInfo");
        }
        //先根据 ID 查询角色信息
        RoleInfoEntity roleInfoEntity = roleInfoService.queryRoleInfoById(VO.getRoId());
        if (null == roleInfoEntity){
            log.error("修改的角色信息不存在，无法进行下一步操作");
            throw new CommonException("CJW202111010046","RoleInfoOperationImpl","insertRoleInfo");
        }
        roleInfoEntity.setUtDt(new Date());
        roleInfoService.updateRoleInfo(roleInfoEntity);

        //修改role_perm表信息
        List<RolePermEntity> rolePermEntityList = new ArrayList<>();
        for (int i = 0;i < VO.getList().size();i++){
            RolePermEntity rolePermEntity = new RolePermEntity();
            rolePermEntity.setRpId(IdUtil.getRPId(i));
            rolePermEntity.setRoId(VO.getRoId());
            rolePermEntity.setPrId(VO.getList().get(i));
            rolePermEntity.setStDt(new Date());
            rolePermEntity.setUtDt(new Date());
            rolePermEntityList.add(rolePermEntity);
        }
        rolePermService.updateBatchRolePerm(rolePermEntityList);
    }

    /**
    * @author: ChengJW
    * @params: [roleInfoVO]
    * @return: void
    * @date: 2021/11/18
    * @description: 删除角色信息
    */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteRoleInfo(RoleInfoVO roleInfoVO) throws CommonException {

        if (null == roleInfoVO || StringUtil.isNull(roleInfoVO.getRoId())){
            log.error("角色信息不存在，无法进行下一步操作");
            throw new CommonException("CJW202111010046","RoleInfoOperationImpl","deleteRoleInfo");
        }

        //判断该角色是否关联用户
        UserRoleEntity userRoleEntity = new UserRoleEntity();
        userRoleEntity.setRoId(roleInfoVO.getRoId());
        List<UserRoleEntity> list = userRoleService.queryUserRoleInfo(userRoleEntity);
        if (null != list && list.size() > 0){
            log.error("该角色已有用户关联，无法进行删除");
            throw new CommonException("CJW202111010047","RoleInfoOperationImpl","deleteRoleInfo");
        }

        RoleInfoEntity entity = new RoleInfoEntity();
        BeanUtils.copyProperties(roleInfoVO,entity);
        roleInfoService.deleteRoleInfo(entity);
        //删除角色-权限信息
        RolePermEntity rolePermEntity = new RolePermEntity();
        rolePermEntity.setRoId(roleInfoVO.getRoId());
        rolePermService.deleteBatchRolePerm(rolePermEntity);
    }

    /**
    * @author: ChengJW
    * @params: [roleInfoVO]
    * @return: void
    * @date: 2021/11/18
    * @description: 校验 roleInfoVO
    */
    public void checkRoleInfo(RoleInfoVO vo) throws CommonException{
        if (null == vo){
            log.error("角色信息为空，无法进行下一步操作");
            throw new CommonException("CJW202111010042","RoleInfoOperationImpl","insertRoleInfo");
        }
        //对角色ID，角色代码，角色名称，角色所属机关代码，角色菜单权限校验是否为空
        if (StringUtil.isNull(vo.getRoId()) || StringUtil.isNull(vo.getRoDesc()) || StringUtil.isNull(vo.getRoNm()) || StringUtil.isNull(vo.getRoCode()) || null == vo.getList() || vo.getList().size() == 0){
            log.error("角色信息填写不完全，无法进行下一步操作");
            throw new CommonException("CJW202111010045","RoleInfoOperationImpl","insertRoleInfo");
        }
        RoleInfoEntity entity = new RoleInfoEntity();
        //根据角色代码进行查询，如果存在，则抛出异常
        entity.setRoNm(vo.getRoNm());
        entity.setRoCode(vo.getRoCode());
        List<RoleInfoEntity> list1 = roleInfoService.queryRoleInfoList(entity);
        if (null != list1 && list1.size() > 0){
            log.error("角色代码已经存在，无法添加角色");
            throw new CommonException("CJW202111010043","RoleInfoOperationImpl","insertRoleInfo");
        }
        //根据角色名称(中文描述)进行查询，如果存在，则抛出异常
        entity.setRoNm(null);
        entity.setRoDesc(vo.getRoDesc());
        List<RoleInfoEntity> list2 = roleInfoService.queryRoleInfoList(entity);
        if (null != list2 && list2.size() > 0){
            log.error("角色代名称已经存在，无法添加角色");
            throw new CommonException("CJW202111010044","RoleInfoOperationImpl","insertRoleInfo");
        }
    }
}
